home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
viewers
/
polyview
/
plyvw102.lha
/
PolyView1.02
/
pvfuncs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-11-13
|
13KB
|
759 lines
/* INCLUDE FILES */
#include "pv.h"
int reset_c(char *);
int step_c(char *);
int twist_c(char *);
int write_c(char *);
parse_t commands[] = {
"from", from_c,
"at", at_c,
"step", step_c,
"twist", twist_c,
"write", write_c,
"reset", reset_c,
NULL, NULL
};
void
init_menus()
{
void exit(int);
/* Define the window pop-up menus */
quit_m = defpup("Confirm%t|Yes, really! %f|No, not really.", exit);
vrender_m = defpup("points%f|lines%f|polygons%f",
point_mode, lines_mode, polygon_mode);
vshade_m = defpup("constant%f|gouraud%f", constant_mode, gouraud_mode);
vproject_m = defpup("perspective%f|orthographic%f", persp_mode,
ortho_mode);
vpalette_m = defpup("from file %F|gray|rainbow|rgb",
palette_pick);
voverlay_m = defpup("at point%f|axes%f|box%f|labels%f|outlines%f",
at_point_tgl, axes_tgl, box_tgl, labels_tgl, outlines_tgl);
vanimate_m = defpup("reverse%f|reverse 1%f|stop%f|forward 1%f|forward%f",
reverse, reverse1, stop, forward1, forward);
view_m = defpup("View %t|project %m|draw %m|shade %m|palette %m|overlay %m%l|Animate %m|Fly|Pop|Redraw|Reset|Write HDF %l|quit %m",
vproject_m, vrender_m, vshade_m, vpalette_m, voverlay_m,
vanimate_m, quit_m);
}
int
parse_and_exec(command, line)
parse_t command[];
char * line;
{
char word[MAXLINELEN];
char subline[MAXLINELEN];
int i;
int (*parse_fn)();
/* Parse the command word and the rest of the line */
word[0] = '\0';
subline[0] = '\0';
sscanf(line, "%s %[^\n]", word, subline);
/* Search for any matches of the command word */
parse_fn = NULL;
for (i = 0; command[i].word != NULL; i++) {
if (strcasecmp(command[i].word, word) == 0) {
if (parse_fn == NULL) {
parse_fn = command[i].parse_fn;
}
else {
return TRUE; /* ERROR: not unique */
}
}
}
/* Call the sub-line parsing function if one was found. */
if (parse_fn != NULL) {
return ((*parse_fn)(subline));
}
else {
return TRUE;
}
}
int
from_c(line)
char * line;
{
char word[MAXLINELEN];
windat_t * window;
float dx, dy, dz, dt;
double fx, fy, fz, ft;
double twistf;
double dist;
float steps;
int num_args;
/* Get the type of move and coordinate vector */
word[0] = '\0';
num_args = sscanf(line, "%s %f %f %f %f", word, &dx, &dy, &dz, &dt);
if ((num_args != 4) && (num_args != 5)) {
printf("syntax error: from type x y z [twist]\n");
return TRUE;
}
/* The default value for twist is the current value */
if (num_args == 4) {
dt = (float) twist;
}
else {
dt *= 10;
}
/* Adjust the new vector based on the type (absolute or relative) */
/* and save their final values */
if (strncasecmp("abs", word, strlen(word)) == 0) {
fx = dx;
fy = dy;
fz = dz;
ft = dt;
dx -= from[X];
dy -= from[Y];
dz -= from[Z];
dt -= twist;
}
else {
fx = dx + from[X];
fy = dy + from[Y];
fz = dz + from[Z];
ft = dt + twist;
if (strncasecmp("rel", word, strlen(word)) != 0) {
printf("from requires 'abs' or 'rel' as ");
printf("a second argument.\n");
}
return TRUE;
}
/* Determine the number of steps necessary to move from the initial */
/* from point to the new from point. If there is no change in */
/* location, use the twist value to determine the twist rate. If */
/* there is no change in twist, quit the function. */
dist = fhypot((double) dx, fhypot((double) dy, (double) dz));
if (dist == 0.0) {
if (dt == 0.0) {
return FALSE;
}
else {
steps = fabs(dt / (step * 500));
}
}
else {
steps = dist / step;
}
/* Calculate the steps sizes for x, y, z, and twist parameters. */
dx /= steps;
dy /= steps;
dz /= steps;
dt /= steps;
/* Move the view, updating after each step */
twistf = (float) twist;
while ((steps >= 1.0) && current.fly_mode) {
/* Adjust the viewing parameters */
from[X] += (float) dx;
from[Y] += (float) dy;
from[Z] += (float) dz;
twistf += dt;
twist = (Angle) twistf;
steps -= 1.0;
cart_to_sphere(from[X]-at[X], from[Y]-at[Y], from[Z]-at[Z],
&rho, &theta, &phi);
/* Redraw the window and check for any other pending events */
if (current.window != NULL) {
qenter(REDRAW, (short) current.active_id);
}
handle_event(windows);
/* If the user terminated the fly-by, get out of here */
/* without any further changes. */
if (!current.fly_mode) return FALSE;
}
/* If there was part of a step left over, adjust the final position */
/* and regenerate the image */
if (steps != 0.0) {
from[X] = fx;
from[Y] = fy;
from[Z] = fz;
twist = ft;
cart_to_sphere(from[X]-at[X], from[Y]-at[Y], from[Z]-at[Z],
&rho, &theta, &phi);
if (current.window != NULL) {
qenter(REDRAW, (short) current.active_id);
}
handle_event(windows);
}
return FALSE;
}
int
at_c(line)
char * line;
{
char word[MAXLINELEN];
windat_t * window;
double nx, ny, nz;
float dx, dy, dz;
double dist;
int steps;
/* Get the type of move and coordinate vector */
word[0] = '\0';
if (sscanf(line, "%s %f %f %f", word, &dx, &dy, &dz) != 4) {
printf("at requires four arguments: type, x, y, z.\n");
return TRUE;
}
/* Adjust the new vector based on the word...*/
if (strncasecmp("rel", word, strlen(word)) == 0) {
dx += at[X];
dy += at[Y];
dz += at[Z];
}
else if (strncasecmp("abs", word, strlen(word)) != 0) {
printf("at requires 'abs' or 'rel' as second argument.\n");
return TRUE;
}
/* Calculate how to move */
dist = fhypot((double)(dx-at[X]), fhypot((double)(dy-at[Y]),
(double)(dz-at[Z])));
nx = (dx - at[X]) / dist * step;
ny = (dy - at[Y]) / dist * step;
nz = (dz - at[Z]) / dist * step;
/* Move the view, updating after each step */
for (steps = dist / step; (steps > 0.0) && current.fly_mode;
steps -= 1.0) {
at[X] += (float) nx;
at[Y] += (float) ny;
at[Z] += (float) nz;
cart_to_sphere(from[X]-at[X], from[Y]-at[Y], from[Z]-at[Z],
&rho, &theta, &phi);
if (current.window != NULL) {
qenter(REDRAW, (short) current.active_id);
}
handle_event(windows);
if (!current.fly_mode) return FALSE;
}
at[X] = dx;
at[Y] = dy;
at[Z] = dz;
cart_to_sphere(from[X]-at[X], from[Y]-at[Y], from[Z]-at[Z],
&rho, &theta, &phi);
if (current.window != NULL) {
qenter(REDRAW, (short) current.active_id);
}
handle_event(windows);
return FALSE;
}
int
step_c(line)
char * line;
{
/* Get the new step size value */
if (sscanf(line, "%f", &step) != 1) {
printf("step requires one argument: stepsize.\n");
return TRUE;
}
return FALSE;
}
int
twist_c(line)
char * line;
{
float angle;
float twist_dist;
Angle new_twist;
int steps;
float nt;
/* Get the new twist angle value */
if (sscanf(line, "%f", &angle) != 1) {
printf("twist requires one argument: angle.\n");
return TRUE;
}
/* Calculate the amount of change in twist required */
new_twist = (Angle) angle * 10;
twist_dist = new_twist - twist;
nt = (step * 500);
if (twist_dist < 0.0) nt = -nt;
/* Change the twist, updating after each step */
for (steps = (int) (twist_dist / nt);
(steps > 0) && current.fly_mode; steps--) {
twist += nt;
if (current.window != NULL) {
qenter(REDRAW, (short) current.active_id);
}
handle_event(windows);
if (!current.fly_mode) return FALSE;
}
if (twist != new_twist) {
twist = new_twist;
if (current.window != NULL) {
qenter(REDRAW, (short) current.active_id);
}
handle_event(windows);
}
return FALSE;
}
int
write_c(line)
char * line;
{
/* Should provide single and auto options, file name, and optional */
/* count between frames */
return FALSE;
}
int
reset_c(line)
char * line;
{
do_reset(10);
return FALSE;
}
int
point_mode(val)
int val;
{
current.points = TRUE;
current.lines = FALSE;
current.polygons = FALSE;
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
lines_mode(val)
int val;
{
current.points = FALSE;
current.lines = TRUE;
current.polygons = FALSE;
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
polygon_mode(val)
int val;
{
current.points = FALSE;
current.lines = FALSE;
current.polygons = TRUE;
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
depth_mode(val)
int val;
{
current.depth = !current.depth;
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
constant_mode(val)
int val;
{
current.constant = TRUE;
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
gouraud_mode(val)
int val;
{
current.constant = FALSE;
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
ortho_mode(val)
int val;
{
current.ortho = TRUE;
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
persp_mode(val)
int val;
{
current.ortho = FALSE;
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
at_point_tgl(val)
int val;
{
current.at_point = !current.at_point;
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
palette_pick(val)
int val;
{
switch (val) {
case 1: /* from file */
build_colormap(LOAD_SPEC);
break;
case 2: /* gray */
build_colormap(GRAY_SPEC);
break;
case 3: /* rainbow */
build_colormap(RBOW_SPEC);
break;
case 4: /* rgb */
build_colormap(RGB_SPEC);
break;
}
}
int
axes_tgl(val)
int val;
{
current.axes = !current.axes;
current.box = FALSE;
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
box_tgl(val)
int val;
{
current.axes = FALSE;
current.box = !current.box;
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
labels_tgl(val)
int val;
{
current.labels = !current.labels;
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
outlines_tgl(val)
int val;
{
if (current.polygons) {
current.outlines = !current.outlines;
qenter(REDRAW, (short) current.active_id);
}
else
if (current.outlines)
current.outlines = !current.outlines;
return 1;
}
int
forward(val)
int val;
{
image_t ** image;
animation.forward = -1;
animation.reverse = 0;
return 1;
}
int
forward1(val)
int val;
{
animation.forward = 1;
animation.reverse = 0;
return 1;
}
int
stop(val)
int val;
{
animation.forward = 0;
animation.reverse = 0;
return 1;
}
int
reverse1(val)
int val;
{
image_t * image;
animation.forward = 0;
animation.reverse = 1;
return 1;
}
int
reverse(val)
int val;
{
image_t * image;
animation.forward = 0;
animation.reverse = -1;
return 1;
}
int
do_fly(val)
int val;
{
if (current.fly_mode) {
current.fly_mode = FALSE;
}
else {
current.fly_mode = TRUE;
if (args_found_arg(args, "fly")) {
if (read_fly_file(flyfile)) {
printf("\nERROR: Problem reading flyfile '%s'.\n",
flyfile);
exit(-1);
}
else {
}
}
else {
printf("\nPlease specify flyfile on command line\n");
printf("using the '-fly' switch for this option.\n");
}
}
/* Turn off the flying now that we are done */
current.fly_mode = FALSE;
return 1;
}
int
do_redraw(val)
int val;
{
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
do_reset(val)
int val;
{
initialize(TRUE);
qenter(REDRAW, (short) current.active_id);
return 1;
}
int
do_pop(val)
int val;
{
winpop();
return 1;
}
int
write_hdf(val)
int val;
{
unsigned char *buff;
int depth, ret, num_bytes;
long xsize, ysize;
long x, y;
Screencoord sx1,sy1,sx2,sy2;
int i, j;
char local_palette[256*3];
/* pop the current window to the top of the screen */
winset(current.active_id);
winpop();
getsize(&x, &y);
/* Calculate the number of bytes required for the screen */
getviewport(&sx1,&sx2,&sy1,&sy2);
xsize = (sx2 - sx1) + 1;
ysize = (sy2 - sy1) + 1;
num_bytes = xsize * ysize * sizeof(char);
buff = (unsigned char *)malloc(num_bytes);
if (!buff) {
printf("%s: Not enough memory\n",main_image.ris8out);
exit(1);
}
/* Copy the palette to the proper format for DFR8setpalette */
for (i = 0; i < 256; i++) {
for (j = 0; j < 3; j++) {
local_palette[i*3+j] = palette[i][j];
}
}
/* Read the screen and write it to the hdf file */
read_scr(&xsize,&ysize,buff);
DFR8setpalette(local_palette);
ret = DFR8putimage(main_image.ris8out,buff,xsize,ysize,11);
if (ret) {
printf("%s: Error with DFR8putimage\n",main_image.ris8out);
exit(1);
}
}
int
read_scr(xsiz,ysiz,ibuff)
long *xsiz,*ysiz;
unsigned char *ibuff;
{
Screencoord sx1,sy1,sx2,sy2;
Coord rx1,ry1,rx2,ry2;
Colorindex *row_cols;
int num_bytes;
register int i,j;
Icoord ix;
short lx;
long jrp;
unsigned char *buf_ptr;
static float idmatrix[4][4] = {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0};
getviewport(&sx1,&sx2,&sy1,&sy2);
*xsiz = (sx2 - sx1) + 1;
*ysiz = (sy2 - sy1) + 1;
rx1 = (Coord)sx1 - 0.5;
ry1 = (Coord)sy1 - 0.5;
rx2 = (Coord)sx2 + 0.5;
ry2 = (Coord)sy2 + 0.5;
pushmatrix();
pushviewport();
loadmatrix(idmatrix);
ortho2(rx1,rx2,ry1,ry2);
lx = (short)(*xsiz);
ix = sx1;
buf_ptr = &ibuff[0];
num_bytes = lx * sizeof(Colorindex);
row_cols = (Colorindex *)malloc(num_bytes);
if (!row_cols){
puts("Not enough memory for row_cols");
exit(1);
}
readsource(SRC_FRONT);
for(j=sy2; j >= sy1; j--){
cmov2i(ix,j);
jrp = readpixels(lx,row_cols);
for(i=0; i<lx; i++)
*buf_ptr++ = (unsigned char)(row_cols[i] - SPEC_BASE);
}
free(row_cols);
popviewport();
popmatrix();
return(0);
}